/***************************************************************************
 *   Copyright (C) 2005 by xihe   *
 *   xihels@163.com                                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef	_DOWN_LOAD_GROUP_FRIEND_H_
#define _DOWN_LOAD_GROUP_FRIEND_H_

#include "Packet.h"
#include "QQBuddy.h"
#include <vector>
using std::vector;

/**
 * 请求下载分组好友列表的消息包，格式为
 * 1. 头部
 * 2. 操作字节标志，下载为0x1
 * 3. 未知字节0x2
 * 4. 未知4字节，全0
 * 5. 起始好友号，如果这是第一个包，全0，
 *	  有时候一个包还下载不完所有的好友，在这里填上起始好友号
 * 6. 尾部
 */

class DownloadGroupFriendPacket : public OutPacket {
    public:
	DownloadGroupFriendPacket(QQClient& cl,
		uint32_t beginFrom_ = 0) : 
	    OutPacket(cl,
		    QQ_CMD_DOWNLOAD_GROUP_FRIEND,
		    SEND_COUNT),
	    beginFrom(beginFrom_)
	{}
	~DownloadGroupFriendPacket(){}
	void setBeginFrom(uint32_t beginFrom_) { beginFrom = beginFrom_; }
	int putBody(uint8_t* buf) const;
    private:
	uint32_t beginFrom;
};

/**
 * 请求下载分组好友列表的回复包，格式为
 * 1. 头部
 * 2. 操作字节，下载为0x1
 * 3. 回复码，1字节
 * 4. 4个未知字节，全0
 * 5. 下一个下载包的起始好友号
 * 6. 好友的QQ号，4字节
 * 7. 好友类型，0x1表示普通好友，0x4表示群
 * 
 * 8. 分组序号，1字节，但是这个很奇怪，不是1，2，3那样的,
 *    而是用序号乘4，比如如果是属于第2个组，
 *    那么这个就是8，注意我的好友组是第0组，
 *    但是有可能这个数字不是4的倍数，那就不知道什么
 *    意思了，但是除以4得到组序号的方法仍然不受影响
 *    
 * 9. 如果还有更多好友，重复4，5，6部分
 * 10. 尾部
 */
class DownloadGroupFriendReplyPacket : public InPacket {
    protected:
	DownloadGroupFriendReplyPacket(const uint8_t* buf, int len);
    public:
	typedef vector<QQGroupFriend> Members;

	const Members& getMembers() const { return members; }

	int	 getBeginFrom() const	 { return beginFrom; }
	uint8_t  getReplyCode() const    { return replyCode; }
	uint8_t  getSubCommand() const   { return subCommand; }

    private:


	Members   members;
	uint32_t  beginFrom;    
	uint8_t   replyCode;
	uint8_t   subCommand; 	
};

/**
 * 上传下载分组名字的消息包，格式为
 * 1. 头部
 * 2. 操作方式字节，如果为0x2，为上传组名，如果为0x1，为请求下载组名
 *    如果为0x2，后面的部分为
 * 	  i.   组序号，qq缺省的组，比如我的好友，序号是0，
 * 	  其他我们自己添加的组，从1开始，一个字节。
 *         但是要注意的是，这里不包括我的好友组，因为我的好友组是QQ的缺省组，无需上传名称
 *    ii.  16个字节的组名，如果组名长度少于16个字节，
 *    后面的填0。之所以是16个，是因为QQ的组名长度最多8个汉字
 *    iii. 如果有更多组，重复i，ii部分
 *    如果为0x1，后面的部分为
 *    i.   未知字节0x2
 *    ii.  4个未知字节，全0 
 * 3. 尾部
 * 
 * 这个包没有限制添加的组名叫什么，也没有明确规定第一个组必须是
 * 我的好友组，这些规范需要在上层程序中实现。当然也可以不一定非要第一个组是
 * 我的好友组，这些客户端的trick随便你怎么搞
 * 
 * 每次上传都必须上传所有组名
 */

class GroupDataOpPacket : public OutPacket {
    public:
	typedef vector<QQGroupName> Members;
	GroupDataOpPacket(QQClient& cl) :
	    OutPacket(cl, QQ_CMD_GROUP_DATA_OP, SEND_COUNT),
	    type(QQ_DOWNLOAD_GROUP_NAME)
	{}
	GroupDataOpPacket(QQClient& cl, Members _members) : 
	    OutPacket(cl, QQ_CMD_GROUP_DATA_OP, true),
	    type(QQ_UPLOAD_GROUP_NAME),
	    members(_members)
	{}
	int putBody(uint8_t* buf) const ;
    private:
	Members members;
	uint8_t type;
};


/**
 * 下载分组名称的回复包，格式为
 * 1. 头部
 * 2. 子命令，1字节，下载是0x1
 * 3. 回复码，1字节
 * 5. 未知的4字节
 * 6. 组序号，从1开始，0表示我的好友组，因为是缺省组，所以不包含在包中
 * 7. 16字节的组信息，开始是组名，以0结尾，如果长度不足16字节，则其余部分可能为0，也可能
 *    为其他字节，含义不明
 * 8. 若有多个组，重复6，7部分
 * 9. 尾部
 * 
 * 上传分组名称的回复包，格式为
 * 1. 头部
 * 2. 子命令，1字节
 * 3. 回复码，1字节
 * 4. 组需要，从1开始，0表示我的好友组，因为是缺省组，所以不包含在包中
 * 5. 如果有更多组，重复4部分
 * 6. 尾部
 */

class GroupDataOpReplyPacket : public InPacket {
    protected:
	GroupDataOpReplyPacket(const uint8_t* buf, int len);
    public:
	typedef vector<QQGroupName> Members;
	const uint8_t getSubCommand() const { return subCommand; }
	const Members& getMembers() const { return members;  }
    private:
	Members members;
	uint8_t subCommand;
};

#endif // _DOWN_LOAD_GROUP_FRIEND_H_

